﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace Noris.Tools.FrxEditor.Data
{
    /// <summary>
    /// Struktura, která popisuje relativní umístění komponenty v rámci jejího ownera (Bandu).
    /// Vnitřně si pamatuje relativní vzdálenosti svých okrajů od souřadnic okrajů ownera, plus svoje rozměry.
    /// Pomocí svých metod GetAbsolute() umožní vrátit standardní RectangleF, který vyjadřuje souřadnice této komponenty v rámci libovolně změněných souřadnic ownera při daném stylu ukotvení.
    /// Tato struktura současně řeší umístění komponent, které mají rozsah přes více bandů (typicky rámečky: začínají na Header, jdou přes Detail a končí na Footer).
    /// Řešení spočívá v práci se dvěma ownery, kdy jeden je Top a druhý Bottom.
    /// Owner na straně Top ovlivňuje souřadnice Left, Top, Right. Owner na straně Bottom ovlivňuje pouze souřadnici Bottom.
    /// </summary>
    public struct RelativeRectangleF
    {
        #region Proměnné
        private float _XBegin;
        private float _XSize;
        private float _XAfter;
        private float _YTopBegin;
        private float _YTopAfter;
        private float _YSize;
        private float _YBottomBegin;
        private float _YBottomAfter;
        #endregion
        #region Public property
        /// <summary>
        /// Vzdálenost Left objektu od souřadnice Left objektu Owner
        /// </summary>
        public float XBegin { get { return this._XBegin; } }
        /// <summary>
        /// Velikost objektu v ose X = šířka
        /// </summary>
        public float XSize { get { return this._XSize; } }
        /// <summary>
        /// Vzdálenost Right objektu od souřadnice Right objektu Owner
        /// </summary>
        public float XAfter { get { return this._XAfter; } }
        /// <summary>
        /// Vzdálenost Top objektu od souřadnice Top objektu OwnerTop
        /// </summary>
        public float YTopBegin { get { return this._YTopBegin; } }
        /// <summary>
        /// Vzdálenost Top objektu od souřadnice Bottom objektu OwnerTop
        /// </summary>
        public float YTopAfter { get { return this._YTopAfter; } }
        /// <summary>
        /// Velikost objektu v ose Y = výška
        /// </summary>
        public float YSize { get { return this._YSize; } }
        /// <summary>
        /// Vzdálenost Bottom objektu od souřadnice Top objektu OwnerBottom
        /// </summary>
        public float YBottomBegin { get { return this._YBottomBegin; } }
        /// <summary>
        /// Vzdálenost Bottom objektu od souřadnice Bottom objektu OwnerBottom
        /// </summary>
        public float YBottomAfter { get { return this._YBottomAfter; } }
        #endregion
        #region Public tvorba instance
        /// <summary>
        /// Vrátí relativní souřadnice komponenty, vzhledem k souřadnicím daného owner bandu (komponenta je jednobandová).
        /// Vstupující souřadnice komponenty jsou v koordinátech pracovní plochy, který vlastní i ownera.
        /// Pokud tedy komponenta má svůj horní okraj identický s horním okrajem ownera, pak vstupující souřadnice Y komponenty není 0, ale je rovna souřadnici Y ownera.
        /// </summary>
        /// <param name="component">Rozměry komponenty</param>
        /// <param name="ownerSize">Velikost hostitele</param>
        /// <returns></returns>
        public static RelativeRectangleF CreateRelative(RectangleF component, SizeF ownerSize)
        {
            return CreateRelative(component.X, component.Y, component.Width, component.Height, ownerSize.Width, ownerSize.Height);
        }
        /// <summary>
        /// Vrátí relativní souřadnice komponenty, vzhledem k souřadnicím daného owner bandu (komponenta je jednobandová).
        /// Vstupující souřadnice komponenty jsou v koordinátech pracovní plochy, který vlastní i ownera.
        /// Pokud tedy komponenta má svůj horní okraj identický s horním okrajem ownera, pak vstupující souřadnice Y komponenty není 0, ale je rovna souřadnici Y ownera.
        /// </summary>
        /// <param name="x">Pozice komponenty X</param>
        /// <param name="y">Pozice komponenty Y</param>
        /// <param name="width">Velikost komponenty Width</param>
        /// <param name="height">Velikost komponenty Height</param>
        /// <param name="ownerWidth">Velikost hostitele Width</param>
        /// <param name="ownerHeight">Velikost hostitele Height</param>
        /// <returns></returns>
        public static RelativeRectangleF CreateRelative(float x, float y, float width, float height, float ownerWidth, float ownerHeight)
        {
            RelativeRectangleF result = new RelativeRectangleF();

            // X se vztahuje pouze k ownerTop:
            result._XBegin = x;
            result._XSize = width;
            result._XAfter = ownerWidth - (x + width);

            // Y:
            result._YSize = height;

            // Y ukládáme jak pro souřadnici Top (relativně k ownerTop), tak pro souřadnici Bottom (ownerBottom):
            result._YTopBegin = y;
            result._YTopAfter = ownerHeight - y;
            result._YBottomBegin = y + height;
            result._YBottomAfter = ownerHeight - (y + height);

            return result;
        }
        /// <summary>
        /// Vrátí relativní souřadnice komponenty, vzhledem k souřadnicím daného owner bandu (komponenta je jednobandová).
        /// Vstupující souřadnice komponenty jsou v koordinátech pracovní plochy, který vlastní i ownera.
        /// Pokud tedy komponenta má svůj horní okraj identický s horním okrajem ownera, pak vstupující souřadnice Y komponenty není 0, ale je rovna souřadnici Y ownera.
        /// </summary>
        /// <param name="component"></param>
        /// <param name="owner"></param>
        /// <returns></returns>
        public static RelativeRectangleF Create(RectangleF component, RectangleF owner)
        {
            RelativeRectangleF result = new RelativeRectangleF();

            // X se vztahuje pouze k ownerTop:
            result._XBegin = component.Left - owner.Left;                  // Relativní pozice komponenty Left vzhledem k owner.Left
            result._XSize = component.Width;
            result._XAfter = owner.Right - component.Right;                // After = vzdálenost od konce (Right) komponenty do konce ownera (owner.Right)

            // Y:
            result._YSize = component.Height;

            // Y ukládáme jak pro souřadnici Top (relativně k ownerTop), tak pro souřadnici Bottom (ownerBottom):
            result._YTopBegin = component.Top - owner.Top;                 // Vzdálenost od Top ownerTop k Top komponenty
            result._YTopAfter = owner.Bottom - component.Top;              // Vzdálenost od Top komponenty k Bottom ownerTop
            result._YBottomBegin = component.Bottom - owner.Top;
            result._YBottomAfter = owner.Bottom - component.Bottom;

            return result;
        }
        /// <summary>
        /// Vrátí relativní souřadnice komponenty, vzhledem k souřadnicím daných dvou owner bandů (top a bottom).
        /// Vstupující souřadnice komponenty jsou v koordinátech pracovní plochy, který vlastní i ownera.
        /// Pokud tedy komponenta má svůj horní okraj identický s horním okrajem ownera, pak vstupující souřadnice Y komponenty není 0, ale je rovna souřadnici Y ownera.
        /// </summary>
        /// <param name="component"></param>
        /// <param name="ownerTop"></param>
        /// <param name="ownerBottom"></param>
        /// <returns></returns>
        public static RelativeRectangleF Create(RectangleF component, RectangleF ownerTop, RectangleF ownerBottom)
        {
            RelativeRectangleF result = new RelativeRectangleF();
            
            // X se vztahuje pouze k ownerTop:
            result._XBegin = component.Left - ownerTop.Left;               // Relativní pozice komponenty Left vzhledem k ownerTop.Left
            result._XSize = component.Width;
            result._XAfter = ownerTop.Right - component.Right;             // After = vzdálenost od konce (Right) komponenty do konce ownera (ownerTop.Right)

            // Y:
            result._YSize = component.Height;

            // Y ukládáme jak pro souřadnici Top (relativně k ownerTop), tak pro souřadnici Bottom (ownerBottom):
            result._YTopBegin = component.Top - ownerTop.Top;              // Vzdálenost od Top ownerTop k Top komponenty
            result._YTopAfter = ownerTop.Bottom - component.Top;           // Vzdálenost od Top komponenty k Bottom ownerTop
            result._YBottomBegin = component.Bottom - ownerBottom.Top;
            result._YBottomAfter = ownerBottom.Bottom - component.Bottom;

            return result;
        }

        /// <summary>
        /// Vrací logické relativní souřadnice na základě dodaných souřadnic logických a daného ViewPortu
        /// </summary>
        /// <param name="visualArea"></param>
        /// <param name="ownerTop"></param>
        /// <param name="ownerBottom"></param>
        /// <param name="viewPortConvertor"></param>
        /// <returns></returns>
        public static RelativeRectangleF CreateLogical(RectangleF visualArea, RectangleF ownerTop, RectangleF ownerBottom, ComponentsLayer.IViewPortConvertor viewPortConvertor)
        {
            RelativeRectangleF result = new RelativeRectangleF();

            // X se vztahuje pouze k ownerTop:
            result._XBegin = _GetLogical(visualArea.Left - ownerTop.Left, viewPortConvertor);     // Relativní pozice komponenty Left vzhledem k ownerTop.Left
            result._XSize = _GetLogical(visualArea.Width, viewPortConvertor);
            result._XAfter = _GetLogical(ownerTop.Right - visualArea.Right, viewPortConvertor);   // After = vzdálenost od konce (Right) komponenty do konce ownera (ownerTop.Right)

            // Y:
            result._YSize = _GetLogical(visualArea.Height, viewPortConvertor);

            // Y ukládáme jak pro souřadnici Top (relativně k ownerTop), tak pro souřadnici Bottom (ownerBottom):
            result._YTopBegin = _GetLogical(visualArea.Top - ownerTop.Top, viewPortConvertor);    // Vzdálenost od Top ownerTop k Top komponenty
            result._YTopAfter = _GetLogical(ownerTop.Bottom - visualArea.Top, viewPortConvertor); // Vzdálenost od Top komponenty k Bottom ownerTop
            result._YBottomBegin = _GetLogical(visualArea.Bottom - ownerBottom.Top, viewPortConvertor);
            result._YBottomAfter = _GetLogical(ownerBottom.Bottom - visualArea.Bottom, viewPortConvertor);

            return result;
        }
        private static float _GetLogical(float visualDimension, ComponentsLayer.IViewPortConvertor viewPortConvertor)
        {
            if (viewPortConvertor == null) return visualDimension;
            return viewPortConvertor.LogicalFromVisual(visualDimension);
        }
        /// <summary>
        /// Obsahuje (vytvoří novou) prázdnou instanci.
        /// </summary>
        public static RelativeRectangleF Empty { get { return new RelativeRectangleF(); } }
        #endregion
        #region Změna souřadnic měřítkem (vytvoření nové instance násobením nebo dělením koeficientem), posuny
        /// <summary>
        /// Násobení koeficientem
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static RelativeRectangleF operator *(RelativeRectangleF a, float b)
        {
            RelativeRectangleF result = new RelativeRectangleF();
            result._XBegin = a._XBegin * b;
            result._XSize = a._XSize * b;
            result._XAfter = a._XAfter * b;
            result._YTopBegin = a._YTopBegin * b;
            result._YTopAfter = a._YTopAfter * b;
            result._YSize = a._YSize * b;
            result._YBottomBegin = a._YBottomBegin * b;
            result._YBottomAfter = a._YBottomAfter * b;
            return result;
        }
        /// <summary>
        /// Násobení koeficientem
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static RelativeRectangleF operator *(RelativeRectangleF a, double b)
        {
            RelativeRectangleF result = new RelativeRectangleF();
            result._XBegin = (float)((double)a._XBegin * b);
            result._XSize = (float)((double)a._XSize * b);
            result._XAfter = (float)((double)a._XAfter * b);
            result._YTopBegin = (float)((double)a._YTopBegin * b);
            result._YTopAfter = (float)((double)a._YTopAfter * b);
            result._YSize = (float)((double)a._YSize * b);
            result._YBottomBegin = (float)((double)a._YBottomBegin * b);
            result._YBottomAfter = (float)((double)a._YBottomAfter * b);
            return result;
        }
        /// <summary>
        /// Dělení koeficientem
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static RelativeRectangleF operator /(RelativeRectangleF a, float b)
        {
            RelativeRectangleF result = new RelativeRectangleF();
            result._XBegin = a._XBegin / b;
            result._XSize = a._XSize / b;
            result._XAfter = a._XAfter / b;
            result._YTopBegin = a._YTopBegin / b;
            result._YTopAfter = a._YTopAfter / b;
            result._YSize = a._YSize / b;
            result._YBottomBegin = a._YBottomBegin / b;
            result._YBottomAfter = a._YBottomAfter / b;
            return result;
        }
        /// <summary>
        /// Dělení koeficientem
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static RelativeRectangleF operator /(RelativeRectangleF a, double b)
        {
            RelativeRectangleF result = new RelativeRectangleF();
            result._XBegin = (float)((double)a._XBegin / b);
            result._XSize = (float)((double)a._XSize / b);
            result._XAfter = (float)((double)a._XAfter / b);
            result._YTopBegin = (float)((double)a._YTopBegin / b);
            result._YTopAfter = (float)((double)a._YTopAfter / b);
            result._YSize = (float)((double)a._YSize / b);
            result._YBottomBegin = (float)((double)a._YBottomBegin / b);
            result._YBottomAfter = (float)((double)a._YBottomAfter / b);
            return result;
        }
        /// <summary>
        /// Posune sebe o daný offset
        /// </summary>
        /// <param name="offset"></param>
        public void ShiftBy(SizeF offset)
        {
            this._XBegin += offset.Width;
            this._XAfter += offset.Width;
            this._YTopBegin += offset.Height;
            this._YTopAfter += offset.Height;
            this._YBottomBegin += offset.Height;
            this._YBottomAfter += offset.Height;
        }
        #endregion
        #region Tvorba absolutních souřadnic na základě this, dodaných souřadnic ownera a stylu ukotvení
        /// <summary>
        /// Vrátí absolutní souřadnice na základě svých uložených dat, pro dané rozměry ownera a styl ukotvení ve směru X a Y.
        /// </summary>
        /// <param name="owner"></param>
        /// <param name="anchorX"></param>
        /// <param name="anchorY"></param>
        /// <returns></returns>
        public RectangleF GetAbsolute(RectangleF owner, AnchorType anchorX, AnchorType anchorY)
        {
            return _GetAbsolute(owner, owner, anchorX, anchorY, null);
        }
        /// <summary>
        /// Vrátí absolutní souřadnice na základě svých uložených dat, pro dané rozměry ownera a styl ukotvení ve směru X a Y.
        /// Své souřadnice násobí zoomem pro daný ViewPort.
        /// </summary>
        /// <param name="owner"></param>
        /// <param name="anchorX"></param>
        /// <param name="anchorY"></param>
        /// <param name="viewPortConvertor"></param>
        /// <returns></returns>
        public RectangleF GetVisual(RectangleF owner, AnchorType anchorX, AnchorType anchorY, ComponentsLayer.IViewPortConvertor viewPortConvertor)
        {
            return _GetAbsolute(owner, owner, anchorX, anchorY, viewPortConvertor);
        }
        /// <summary>
        /// Vrátí absolutní souřadnice na základě svých uložených dat, pro dané rozměry ownerů a styl ukotvení ve směru X a Y.
        /// </summary>
        /// <param name="ownerTop"></param>
        /// <param name="ownerBottom"></param>
        /// <param name="anchorX"></param>
        /// <param name="anchorY"></param>
        /// <returns></returns>
        public RectangleF GetAbsolute(RectangleF ownerTop, RectangleF ownerBottom, AnchorType anchorX, AnchorType anchorY)
        {
            return _GetAbsolute(ownerTop, ownerBottom, anchorX, anchorY, null);
        }
        /// <summary>
        /// Vrátí absolutní souřadnice na základě svých uložených dat, pro dané rozměry ownerů a styl ukotvení ve směru X a Y.
        /// Své souřadnice násobí zoomem pro daný ViewPort.
        /// </summary>
        /// <param name="ownerTop"></param>
        /// <param name="ownerBottom"></param>
        /// <param name="anchorX"></param>
        /// <param name="anchorY"></param>
        /// <param name="viewPortConvertor"></param>
        /// <returns></returns>
        public RectangleF GetVisual(RectangleF ownerTop, RectangleF ownerBottom, AnchorType anchorX, AnchorType anchorY, ComponentsLayer.IViewPortConvertor viewPortConvertor)
        {
            return _GetAbsolute(ownerTop, ownerBottom, anchorX, anchorY, viewPortConvertor);
        }
        /// <summary>
        /// Vrátí absolutní souřadnice na základě svých uložených dat, pro dané rozměry ownerů a styl ukotvení ve směru X a Y.
        /// Své souřadnice násobí daným zoomem.
        /// </summary>
        /// <param name="ownerTop"></param>
        /// <param name="ownerBottom"></param>
        /// <param name="anchorX"></param>
        /// <param name="anchorY"></param>
        /// <param name="viewPortConvertor"></param>
        /// <returns></returns>
        private RectangleF _GetAbsolute(RectangleF ownerTop, RectangleF ownerBottom, AnchorType anchorX, AnchorType anchorY, ComponentsLayer.IViewPortConvertor viewPortConvertor)
        {
            float l = 0f;
            float t = 0f;
            float r = 0f;
            float b = 0f;

            // Osa X:
            this._GetAbsoluteX(ownerTop, anchorX, viewPortConvertor, ref l, ref r);

            // Osa Y:
            this._GetAbsoluteY(ownerTop, ownerBottom, anchorY, viewPortConvertor, ref t, ref b);

            // Hotovo:
            return RectangleF.FromLTRB(l, t, r, b);
        }
        /// <summary>
        /// Určí absolutní souřadnice na ose X pro daného ownera a typ ukotvení, vycházejíc ze svých proměnných
        /// </summary>
        /// <param name="owner"></param>
        /// <param name="anchorX"></param>
        /// <param name="viewPortConvertor"></param>
        /// <param name="l"></param>
        /// <param name="r"></param>
        private void _GetAbsoluteX(RectangleF owner, AnchorType anchorX, ComponentsLayer.IViewPortConvertor viewPortConvertor, ref float l, ref float r)
        {
            switch (anchorX)
            {
                case AnchorType.After:
                    // Objekt je ukotven doprava, Width zůstává, mění se Left:
                    r = owner.Right - _GetDim(this._XAfter, viewPortConvertor);
                    l = r - _GetDim(this._XSize, viewPortConvertor);
                    break;
                case AnchorType.Both:
                    // Objekt je ukotven na obě strany, mění se Width:
                    l = owner.Left + _GetDim(this._XBegin, viewPortConvertor);
                    r = owner.Right - _GetDim(this._XAfter, viewPortConvertor);
                    break;
                default:
                    // Objekt je ukotven vlevo, Width zůstává, mění se Right:
                    l = owner.Left + _GetDim(this._XBegin, viewPortConvertor);
                    r = l + _GetDim(this._XSize, viewPortConvertor);
                    break;
            }
        }
        /// <summary>
        /// Určí absolutní souřadnice na ose Y pro dané ownery a typ ukotvení, vycházejíc ze svých proměnných
        /// </summary>
        /// <param name="ownerTop"></param>
        /// <param name="ownerBottom"></param>
        /// <param name="anchorY"></param>
        /// <param name="viewPortConvertor"></param>
        /// <param name="t"></param>
        /// <param name="b"></param>
        private void _GetAbsoluteY(RectangleF ownerTop, RectangleF ownerBottom, AnchorType anchorY, ComponentsLayer.IViewPortConvertor viewPortConvertor, ref float t, ref float b)
        {
            switch (anchorY)
            {
                case AnchorType.After:
                    // Objekt je ukotven dolů: obě souřadnice (top i bottom) se určují od souřadnice Bottom a After patřičného ownera:
                    t = ownerTop.Bottom - _GetDim(this._YTopAfter, viewPortConvertor);
                    b = ownerBottom.Bottom - _GetDim(this._YBottomAfter, viewPortConvertor);
                    break;
                case AnchorType.Both:
                    // Objekt je ukotven na obě strany: souřadnice Top se určí odvrchu, Bottom odspodu:
                    t = ownerTop.Top + _GetDim(this._YTopBegin, viewPortConvertor);
                    b = ownerBottom.Bottom - _GetDim(this._YBottomAfter, viewPortConvertor);
                    break;
                default:
                    // Objekt je ukotven nahoru: obě souřadnice (top i bottom) se určují od souřadnice Top a Begin patřičného ownera:
                    t = ownerTop.Top + _GetDim(this._YTopBegin, viewPortConvertor);
                    b = ownerBottom.Top + _GetDim(this._YBottomBegin, viewPortConvertor);
                    break;
            }
        }
        /// <summary>
        /// Vrací danou dimenzi vynásobenou zoomem.
        /// </summary>
        /// <param name="dimension"></param>
        /// <param name="viewPortConvertor"></param>
        /// <returns></returns>
        private float _GetDim(float dimension, ComponentsLayer.IViewPortConvertor viewPortConvertor)
        {
            if (viewPortConvertor == null) return dimension;
            return viewPortConvertor.VisualFromLogical(dimension);
        }
        #endregion
        #region Serializace, deserializace
        /// <summary>
        /// Vrátí instanci, do které vloží data z XML stringu
        /// </summary>
        /// <returns></returns>
        public static RelativeRectangleF FromXmlSerialData(string xmlSerialData)
        {
            RelativeRectangleF result = new RelativeRectangleF();
            result.XmlSerialData = xmlSerialData;
            return result;
        }
        /// <summary>
        /// String, který je možno použít pro serializaci / deserializaci dat
        /// </summary>
        public string XmlSerialData
        {
            get
            {
                string result = 
                    Convertor.SingleToString(this._XBegin) + ";" + 
                    Convertor.SingleToString(this._XSize) + ";" + 
                    Convertor.SingleToString(this._XAfter) + ";" + 
                    Convertor.SingleToString(this._YTopBegin) + ";" + 
                    Convertor.SingleToString(this._YTopAfter) + ";" + 
                    Convertor.SingleToString(this._YSize) + ";" + 
                    Convertor.SingleToString(this._YBottomBegin) + ";" + 
                    Convertor.SingleToString(this._YBottomAfter);
                return result;
            }
            set
            {
                this._Clear();

                if (String.IsNullOrEmpty(value)) return;
                string[] parts = value.Split(';');
                if (parts.Length < 8) return;

                this._XBegin = (float)Convertor.StringToSingle(parts[0]);
                this._XSize = (float)Convertor.StringToSingle(parts[1]);
                this._XAfter = (float)Convertor.StringToSingle(parts[2]);
                this._YTopBegin = (float)Convertor.StringToSingle(parts[3]);
                this._YTopAfter = (float)Convertor.StringToSingle(parts[4]);
                this._YSize = (float)Convertor.StringToSingle(parts[5]);
                this._YBottomBegin = (float)Convertor.StringToSingle(parts[6]);
                this._YBottomAfter = (float)Convertor.StringToSingle(parts[7]);
            }
        }
        private void _Clear()
        {
            this._XBegin = 0f;
            this._XSize = 0f;
            this._XAfter = 0f;
            this._YTopBegin = 0f;
            this._YTopAfter = 0f;
            this._YSize = 0f;
            this._YBottomBegin = 0f;
            this._YBottomAfter = 0f;
        }
        #endregion
    }
    #region enum AnchorType
    /// <summary>
    /// Ukotvení pozice vzhledem k hostiteli, v jedné ose.
    /// Ukotvení může být k počátku (Begin), nebo ke konci (After) nebo k oběma hranám (Both).
    /// </summary>
    [Flags]
    public enum AnchorType
    {
        /// <summary>
        /// Bez ukotvení. Této hodnotě se komponenta má bránit (default = Begin).
        /// </summary>
        None = 0,
        /// <summary>
        /// Ukotvení k Begin (Top nebo Left).
        /// Zůstává rozměr Begin (Top nebo Left) i velikost Size (Height nebo Width) a tedy i End, přiměřeně se mění rozměr After (Bottom nebo Right).
        /// </summary>
        Begin = 1,
        /// <summary>
        /// Ukotvení k After (Bottom nebo Right).
        /// Zůstává rozměr After (Bottom nebo Right) i velikost Size (Height nebo Width), přiměřeně se mění rozměr Begin (Top nebo Left) a tedy i End.
        /// </summary>
        After = 2,
        /// <summary>
        /// Ukotvení k Begin i After
        /// Zůstává rozměr Begin (Top nebo Left) i After (Bottom nebo Right), přiměřeně se mění velikost Size (Height nebo Width) a tedy i End.
        /// </summary>
        Both = 3
    }
    #endregion
}
